import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './user.entity';
import { CreateUserDto } from './dto/create-user.dto';
import * as bcrypt from 'bcrypt';

@Injectable()
export class UserService {
  constructor(
    @InjectRepository(User)
    private readonly userRepository: Repository<User>,
  ) {}

  async create(createUserDto: CreateUserDto): Promise<User> {
    const user = new User();
    user.username = createUserDto.username;
    user.password = await bcrypt.hash(createUserDto.password, 10);
    user.level = createUserDto.level;

    if (createUserDto.parentId) {
      const parent = await this.userRepository.findOne({ where: { id: createUserDto.parentId } });
      if (parent) {
        user.parent = parent;
      }
    }

    return this.userRepository.save(user);
  }

  async findOne(username: string): Promise<User | undefined> {
    const user = await this.userRepository.findOne({ where: { username }, relations: ['parent', 'children'] });
    return user || undefined;
  }
  
  async findByUsername(username: string): Promise<User | undefined> {
    return this.findOne(username);
  }

  async findById(id: number): Promise<User | undefined> {
    const user = await this.userRepository.findOne({ where: { id }, relations: ['parent', 'children', 'projects'] });
    return user || undefined;
  }
  
  async findAll(): Promise<User[]> {
    return this.userRepository.find({
      relations: ['parent', 'children'],
      order: { id: 'ASC' }
    });
  }
  
  async update(id: number, updateData: any): Promise<User> {
    const user = await this.findById(id);
    if (!user) {
      throw new NotFoundException(`用户ID ${id} 不存在`);
    }
    
    // 如果更新包含密码，需要加密
    if (updateData.password) {
      updateData.password = await bcrypt.hash(updateData.password, 10);
    }
    
    // 更新用户数据
    Object.assign(user, updateData);
    
    return this.userRepository.save(user);
  }
  
  async remove(id: number): Promise<void> {
    const user = await this.findById(id);
    if (!user) {
      throw new NotFoundException(`用户ID ${id} 不存在`);
    }
    
    await this.userRepository.remove(user);
  }

  async getSubordinates(userId: number): Promise<User[]> {
    const manager = await this.userRepository.findOne({ where: { id: userId }, relations: ['children'] });
    if (!manager) {
        return [];
    }

    let subordinates = [...manager.children];
    for (const child of manager.children) {
        const subSubordinates = await this.getSubordinates(child.id);
        subordinates = [...subordinates, ...subSubordinates];
    }

    return subordinates;
  }

  async getSuperiors(userId: number): Promise<User[]> {
    const user = await this.userRepository.findOne({ where: { id: userId }, relations: ['parent'] });
    if (!user || !user.parent) {
        return [];
    }

    const superiors = [user.parent];
    const parentSuperiors = await this.getSuperiors(user.parent.id);
    superiors.push(...parentSuperiors);

    return superiors;
  }
}